package com.stars.easyms.base.util;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.Set;

/**
 * <p>className: SpringBootUtil</p>
 * <p>description: SpringBoot相关工具类</p>
 *
 * @author guoguifang
 * @date 2019-09-12 15:40
 * @since 1.3.1
 */
public final class SpringBootUtil {

    private static final String SPRING_BOOT_VERSION = SpringBootVersion.getVersion();

    private static SpringApplication springApplication;

    private static String[] args;

    private static String springApplicationPackageName;

    private static String applicationName;

    private static String activeProfile;

    public static synchronized void setSpringApplication(SpringApplication springApplication, String[] args) {
        if (SpringBootUtil.springApplication == null) {
            SpringBootUtil.springApplication = springApplication;
            SpringBootUtil.args = args;
        }
    }

    public static synchronized void setSpringApplicationPackageName(String springApplicationPackageName) {
        if (SpringBootUtil.springApplicationPackageName == null) {
            SpringBootUtil.springApplicationPackageName = springApplicationPackageName;
        }
    }

    public static SpringApplication getSpringApplication() {
        return springApplication;
    }

    public static String[] getSpringApplicationArgs() {
        return args;
    }

    public static String getSpringBootVersion() {
        return SPRING_BOOT_VERSION;
    }

    @Nullable
    public static synchronized String getSpringApplicationPackageName() {
        if (springApplicationPackageName == null) {
            Set<Class<?>> springBootApplicationClassSet = ReflectUtil.getAllClassByAnnotation(SpringBootApplication.class);
            if (springBootApplicationClassSet.isEmpty()) {
                springBootApplicationClassSet = ReflectUtil.getAllClassByAnnotation(SpringBootConfiguration.class);
            }
            if (!springBootApplicationClassSet.isEmpty()) {
                springApplicationPackageName = springBootApplicationClassSet.stream()
                        .filter(s -> !s.isArray() && !s.isInterface() && !s.isAnnotation() && !s.isEnum())
                        .map(s -> s.getPackage().getName())
                        .findFirst()
                        .orElse(null);
            }
        }
        return springApplicationPackageName;
    }

    @Nullable
    public static synchronized String getApplicationName() {
        if (applicationName == null) {
            applicationName = PropertyPlaceholderUtil.replace("spring.application.name", null);
            if (applicationName == null) {
                applicationName = ApplicationContextHolder.getApplicationContext().getId();
            }
        }
        return applicationName;
    }

    @NonNull
    public static synchronized String getActiveProfile() {
        if (activeProfile == null) {
            activeProfile = PropertyPlaceholderUtil.replace("spring.profiles.active", "");
        }
        return activeProfile;
    }

    private SpringBootUtil() {
    }
}